﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using XPathAutoSuggest;
using NSubstitute;

namespace XPathToolTests {
    /// <summary>
    /// Tests important functionality of the main window ViewModel using NUnit
    /// </summary>
    /// <remarks>
    /// This project outputs a dll that is designed to be loaded into a tool like NUnit.
    /// </remarks>
    [TestFixture]
    public class MainWindow_ViewModelTests {
        private string _SampleXml = @"<?xml version=""1.0"" encoding=""ISO-8859-1""?>
                                    <bookstore>
                                        <!--Comment-->
                                        <book>
                                          <title lang=""eng"">Harry Potter</title>
                                          <price>29.99</price>
                                        </book>
                                        <book>
                                            <![CDATA[
                                            function matchwo(a,b)
                                            {
                                            if (a < b && a < 0) then
                                              {
                                              return 1;
                                              }
                                            else
                                              {
                                              return 0;
                                              }
                                            }
                                            ]]>
                                        </book>

                                        <book>
                                          <title lang=""eng"">Learning XML</title>
                                          <price>39.95</price>
                                        </book>
                                        <book>
                                          <title lang=""fr"">Nodes for Dummies</title>
                                          <price>3.95</price>
                                        </book>

                                    </bookstore>";


        [Test]
        public void OpenCommandExecute_Sets_Status_And_Xml() {
            IFileIoHelper mockFileIoHelper = Substitute.For<IFileIoHelper>();
            string xml = "<Bookstore />";
            mockFileIoHelper.ReadFile(Arg.Any<string>()).Returns<string>(xml);
            string myFileName = "MyFileName";
            mockFileIoHelper.GetOpenFileName().Returns<string>(myFileName);

            IXPathUtility myXpathUtility = new XmlHelper();
            ModelView_MainWindow vm = new ModelView_MainWindow(myXpathUtility, mockFileIoHelper);
            vm.OpenCommandExecute();
            Assert.AreEqual(xml, vm.FormattedXml, xml);
            Assert.AreEqual("Loaded file '" + myFileName + "'", vm.StatusInfo, "File name not set correctly");
        }

        [Test]
        public void NewCommand_Resets_FileName_And_Xml() {
            ModelView_MainWindow vm = new ModelView_MainWindow(null, null);
            vm.FileName = "MyFileName";
            vm.FormattedXml = "<Bookstore />";
            vm.NewExecute();

            Assert.AreEqual(string.Empty, vm.FormattedXml, "Failed to reset the Formmated XML when New command was issued");
            Assert.AreEqual(string.Empty, vm.FileName);
        }

        [Test]
        public void SuggestExecute_Test() {
            XmlHelper myXmlHelper = new XmlHelper();
            ModelView_MainWindow vm = new ModelView_MainWindow(myXmlHelper, null);
            vm.SelectedXml = "Learning XML";
            vm.SelectionStart = _SampleXml.IndexOf("Learning XML");
            vm.FormattedXml = _SampleXml;

            vm.SuggestExecute();
            Assert.AreEqual(vm.QuerySuggestions.Count, 3);
            Assert.IsTrue(vm.QuerySuggestions.Any(qp => qp.Query == "/bookstore/book/title"),
                                "Suggestion list does not have basic XPath query");
            Assert.IsTrue(vm.QuerySuggestions.Any(qp => qp.Query == "/bookstore[1]/book[3]/title[1]"),
                                            "Suggestion list does not have an indexed suggestion");
            Assert.IsTrue(vm.QuerySuggestions.Any(qp => qp.Query == "/bookstore/book[title=\"Learning XML\"]/title"),
                                "Suggestion list does not have a suggestion utilizing node value");
        }

        [Test]
        public void FormatCommandValidate_Test() {
            XmlHelper myXmlHelper = new XmlHelper();
            ModelView_MainWindow vm = new ModelView_MainWindow(myXmlHelper, null);
            vm.FormattedXml = _SampleXml;
            vm.ShowMessageBoxes = false;

            //vm.FormatCommandExecute();
            //Assert.Greater(vm.FormattedXml.Length, 0, "Formatting the XML resulted in invalid XML");
            vm.ValidateXmlCommandExecute();
            Assert.AreEqual(vm.StatusInfo, string.Empty, "XML not valid after formatting");
        }

        [Test]
        public void EvaluateExecute_XPath_Is_Correct() {
            XmlHelper myXmlHelper = new XmlHelper();
            ModelView_MainWindow vm = new ModelView_MainWindow(myXmlHelper, null);
            vm.FormattedXml = _SampleXml;

            vm.EvaluateExecute("/bookstore/book/title");
            Assert.AreEqual("Harry Potter (3 total hits)", vm.XPathResults);
        }

        /*
            [Test]
            public void SaveCommandExecute_Sets_StatusInfo() {
                IFileIoHelper myFileIoHelper = Substitute.For<IFileIoHelper>();

                bool isDirty = true;
                string statusInfo = string.Empty;
                //myFileIoHelper.SaveToFile(Arg.Any<string>(), Arg.Any<string>(), ref Arg.Do<bool>(d => d = false), ref Arg.Do<string>(s => s = "Saved XML to Some FileName");

                myFileIoHelper
                        .When(x => x.SaveToFile(Arg.Any<string>(), Arg.Any<string>(), ref isDirty, ref statusInfo))
                        .Do(x => { x[2] = false; x[3] = "Saved XML to " + x[1]; });

                myFileIoHelper.SaveToFile("", "Test", ref isDirty, ref statusInfo);
                Assert.AreEqual("Saved XML to Test", statusInfo);

                myFileIoHelper.GetSaveFileName().Returns<string>("MyFileName");

                ModelView_MainWindow vm = new ModelView_MainWindow(null, myFileIoHelper);
                vm.SaveCommandExecute();

                Assert.AreEqual("Saved XML to MyFileName", vm.StatusInfo, "SaveCommandExecute did not update status info");
                Assert.AreEqual(false, isDirty, "After saving, dirty state should be false");
            }
        */
    }
}
